home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
data
/
happypas
/
mineswep.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-11-30
|
6KB
|
157 lines
{*********************************************************************
* *** マインスイーパー *** *
* *
* HAPPyのサンプルプログラム *
* (作者 浅野比富美 Public Domain Software) *
*********************************************************************}
program MineSweeper(input,output) ;
{ 8×8のマス目に10個の地雷が仕掛けてあります。この10個の地雷を
避けた54のマスを陣地として無事取ることができればクリアというゲーム
です。マスを開くと、そのマスの縦横斜めに何個の地雷があるかを数字で
表示してくれます。この数字を頼りにマスを開いていくわけですが、地雷に
当たればそこでゲームオーバーとなります。}
label 999 ; { 地雷に当たった時のゲームオーバー用ラベル }
const N = 8 ; { 盤の一辺のサイズ }
M = 9 ; { N+1 実際の配列は上下左右に1つずつ余分がある }
MaxMine = 10 ; { 地雷の数 }
type TableRange = 0 .. M ; { 盤のレンジ }
TableStatus = (Empty,Mine,Ground) ; { 盤の状態 (空、地雷、陣地) }
PrintMode = (Normal,MinePrint) ; { 盤印字 (通常、地雷出力) }
var Table : array[TableRange,TableRange] of TableStatus ; { 盤 }
RD : integer ; { 乱数発生で使用 }
Remainder : integer ; { 残りの陣地数 }
{*********************************}
{* k未満の乱数を乗算合同法で発生 *}
{*********************************}
function rand(k:integer): integer;
const MaxInteger = 32767 ;
begin
RD := RD * 259 ;
if RD > MaxInteger then RD := RD mod MaxInteger ;
rand := RD mod k
end { rand };
{**************************}
{* 初期設定 *}
{**************************}
procedure Init ;
var x,y : TableRange ;
i : integer ;
begin
repeat
write('乱数の初期値を入れて下さい(0以外) ? ');
readln(RD)
until RD <> 0 ; { 0では計算できないので再入力 }
for x:=0 to M do
for y := 0 to M do
Table[x,y] := Empty ; { 全エリアを空に初期設定 }
for i := 1 to MaxMine do { MaxMine分の地雷を埋め込む }
begin
repeat
x := rand(N)+1 ; y := rand(N)+1 ; { 1~Nまでの乱数発生 }
until Table[x,y] = Empty ; { 空でなければ繰り返す }
Table[x,y] := Mine { 地雷を埋め込む }
end ;
Remainder := sqr(N) - MaxMine { 残り地雷数を初期設定 }
end { Init } ;
{**************************}
{* 盤の印字 *}
{**************************}
procedure Print(mode : PrintMode) ;
type line = packed array[1..4] of char ; { 長さ4の文字列 }
var x,y : TableRange ;
MineNumber : integer ; { 八方の地雷数 }
{***** 横線の印字処理 *****}
procedure Hline(left,mid,right : line) ;
var y : TableRange ;
begin
write(left);
for y:=1 to N-1 do write(mid) ;
writeln(right)
end { Hline } ;
begin { Print }
writeln ;
Hline(' ┏','━┳','━┓') ; { 一番上の横線 }
for x:=1 to N do
begin
write(' ┃') ;
for y:=1 to N do
begin
case Table[x,y] of
Ground : begin { 陣地の時 }
MineNumber := { 地雷数を求める }
ord(Table[x-1,y-1]=Mine) + ord(Table[x-1,y ]=Mine)
+ ord(Table[x-1,y+1]=Mine) + ord(Table[x ,y-1]=Mine)
+ ord(Table[x ,y+1]=Mine) + ord(Table[x+1,y-1]=Mine)
+ ord(Table[x+1,y ]=Mine) + ord(Table[x+1,y+1]=Mine) ;
write(chr(27),'[7m',MineNumber:2,chr(27),'[0m')
{ リバースで地雷数を表示 }
end ;
Empty : write((x-1)*N+y-1:2) ; { 空の時、座標を表示 }
Mine : if mode=Normal then write((x-1)*N+y-1:2) { 座標表示 }
else write('★') { 地雷表示 }
end ;
write('┃')
end ;
writeln ;
if x <> N then Hline(' ┣','━╋','━┫') { 中間の横線 }
else Hline(' ┗','━┻','━┛') { 一番下の横線 }
end ;
writeln('残り陣地は',Remainder:2)
end { Print } ;
{**********************}
{* 陣地座標を入力 *}
{**********************}
procedure InputPoint ;
var x,y : TableRange ;
point : integer ;
ok : Boolean ;
begin
writeln ;
repeat
write('取る陣地を上の数字で入れて下さい ? ') ;
readln(point) ;
ok := (0 <= point) and (point < sqr(N)) ;
if ok then
begin
x := point div N + 1 ; y := point mod N + 1 ; { 対応するx,y座標 }
if Table[x,y] = Mine then { 地雷に当たった時 }
begin
writeln('地雷に当たりました!') ;
goto 999 { ゲームオーバー }
end ;
ok := (Table[x,y] = Empty) { 空ならOK }
end
until ok ; { OKでない時はもう一度入力 }
Table[x,y] := Ground ; { 陣地を取った }
Remainder := Remainder - 1 { 残り陣地数 }
end { InputPoint } ;
{**********************}
{* メイン処理 *}
{**********************}
begin
Init ; { 初期設定 }
repeat
Print(Normal) ; { 盤を印字 }
InputPoint { 陣地を入力 }
until Remainder = 0 ; { 残り陣地があれば繰り返す }
999 : { ゲームオーバー用のラベル }
Print(MinePrint) ; { 地雷場所を印字 }
if Remainder = 0 then writeln('**** クリア! ****')
else writeln('**** ゲームオーバー!****')
end.